package com.study.thread;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.sql.SQLOutput;
import java.util.concurrent.*;

/**
 * @Author hupengming
 * @ClassName TestCompletableFuture
 * @Date 2023-05-19  14:42
 * @Version 1.0
 */
public class TestCompletableFuture {

    /**
     * 无返回值，使用默认线程池
     */
    public static void m1() throws Exception {
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            System.out.println("线程名称：" + Thread.currentThread().getName());
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        System.out.println(voidCompletableFuture.get());
    }

    /**
     * 无返回值，使用自定义线程池
     *
     * @throws Exception
     */
    public static void m2() throws Exception {

        ExecutorService executorService = Executors.newFixedThreadPool(2);

        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {
            System.out.println("线程名称：" + Thread.currentThread().getName());
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }, executorService);

        System.out.println(voidCompletableFuture.get());

        executorService.shutdown();
    }


    /**
     * 有返回值，
     */
    public static void m3() throws Exception {

        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("线程名称：" + Thread.currentThread().getName());
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "hello supplyAsync";
        });

        System.out.println(stringCompletableFuture.get());
    }

    /**
     * 有返回值，自定义线程池
     */
    public static void m4() throws Exception {

        ExecutorService executorService = Executors.newFixedThreadPool(3);

        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("线程名称：" + Thread.currentThread().getName());
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "hello supplyAsync";
        },executorService);

        System.out.println(stringCompletableFuture.get());
        //关闭线程池
        executorService.shutdown();
    }

    public static void m5() throws Exception{
        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {

            System.out.println("线程名称：" + Thread.currentThread().getName());
            int result = ThreadLocalRandom.current().nextInt(10);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "hello supplyAsync. result:" + result;
        });

        System.out.println("主线程继续执行");

        System.out.println("返回结果：" + stringCompletableFuture.get());
    }

    public static void m6(){
        CompletableFuture<Integer> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {

            System.out.println("线程名称：" + Thread.currentThread().getName());
            int result = ThreadLocalRandom.current().nextInt(10);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return result;
        }).whenComplete((i,e) -> {
            if(null == e){
                System.out.println("第一阶段完成，现在执行第二阶段....");
                System.out.println(i);
                System.out.println("第二阶段执行完毕.....");
            }
        }).exceptionally(e -> {
            System.out.println("程序异常....");
            System.out.println(e.getCause() + "---" + e.getMessage());
            e.printStackTrace();
            return null;
        });

        System.out.println("主线程继续执行");

//        System.out.println("返回结果：" + stringCompletableFuture.get());

        System.out.println("返回结果：" + stringCompletableFuture.join());

    }


    public static void main(String[] args){

        m6();
    }

}
